/************************************************************************
Copyright 2003, 2004, 2005, 2006, 2007, 2008 Grid Technology Research Center,
National Institute of Advanced Industrial Science and Technology.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/

package jp.aist.gtrc.plus.scheduler.specific.sge.status;

import java.util.Collection;

import jp.aist.gtrc.plus.scheduler.specific.sge.jaxb.common.*;
import jp.aist.gtrc.plus.scheduler.status.Status;

public class SGEParallelEnv implements Status {

	public static final int ALLOC_RULE_PE_SLOTS = -1;
	public static final int ALLOC_RULE_ROUND_ROBIN = -2;
	public static final int ALLOC_RULE_FILL_UP = -3;

	private static final int ALLOC_RULE_DEFAULT = ALLOC_RULE_PE_SLOTS;
	private static final int ALLOC_RULE_UNKNOWN = 0;

	private final JAXBSGEPe pe;
	private SGEACL acl;
	private int allocRule = ALLOC_RULE_UNKNOWN;

	public SGEParallelEnv(JAXBSGEPe pe) {

		assert(pe != null);
		this.pe = pe;

	}

	public String getName() {

		return pe.getPEName();

	}

	public int getSlotNum() {

		return pe.getPESlots();

	}

	private int parseAllocationRule() {

		String r = pe.getPEAllocationRule();
		if (r.startsWith("$") == false) {
			int v;
			try {
				v = Integer.parseInt(r);
				if (v > 0)
					return v;
			} catch (NumberFormatException e) {
			}
			// rule is not positive / invalid
			return ALLOC_RULE_DEFAULT;
		}

		if (r.equals("$pe_slots"))
			return ALLOC_RULE_PE_SLOTS;
		if (r.equals("$round_robin"))
			return ALLOC_RULE_ROUND_ROBIN;
		if (r.equals("$fill_up"))
			return ALLOC_RULE_FILL_UP;

		assert(false);
		return ALLOC_RULE_DEFAULT;

	}

	public int getAllocationRule() {

		if (allocRule == ALLOC_RULE_UNKNOWN)
			allocRule = parseAllocationRule();
		return allocRule;

	}

	public boolean isProcessPerNodeSpecified() {

		return (getAllocationRule() > 0);

	}

	private Collection<USElement> getUSentries(PEUserList acl) {

		return (acl != null) ? acl.getUSElement() : null;

	}

	private SGEACL makeAcl() {

		SGEUserACL userAcl = SGEUserACL.getInstance(
				getUSentries(pe.getPEUserList()),
				getUSentries(pe.getPEXuserList()));
		return new SGEACL(userAcl); // SGEParallelEnv doesn't have projACL

	}

	public SGEACL getAcl() {

		if (acl == null)
			acl = makeAcl();
		return acl;

	}

	public String toSting() {

		String s = super.toString();
		s += "\nACL " + getAcl().toString();
		s += "\nAllocRule " + getAllocationRule();

		return s;

	}

}
